package top.hymsk.ecommerce.service.impl;

import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.hymsk.ecommerce.config.BaseUrlConfig;
import top.hymsk.ecommerce.dao.elasticsearch.ElasticSearchMapper;
import top.hymsk.ecommerce.dao.mapper.ProductMapper;
import top.hymsk.ecommerce.pojo.DO.CommentShowDO;
import top.hymsk.ecommerce.pojo.DTO.CommentListDTO;
import top.hymsk.ecommerce.pojo.DTO.BaseProductDTO;
import top.hymsk.ecommerce.pojo.DTO.ProductResponseDTO;
import top.hymsk.ecommerce.pojo.PO.mysql.ProductPO;
import top.hymsk.ecommerce.pojo.response.GeneralResponse;
import top.hymsk.ecommerce.pojo.status.ProductStatusCode;
import top.hymsk.ecommerce.pojo.status.ResponseStatusCode;
import top.hymsk.ecommerce.service.ProductService;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 花于陌上开
 */
@Service
public class ProductServiceImpl implements ProductService {
    private final ProductMapper productMapper;
    private final ElasticSearchMapper elasticSearchMapper;
    private final BaseUrlConfig baseUrlConfig;

    public ProductServiceImpl(ProductMapper productMapper, ElasticSearchMapper elasticSearchMapper, BaseUrlConfig baseUrlConfig) {
        this.productMapper = productMapper;
        this.elasticSearchMapper = elasticSearchMapper;
        this.baseUrlConfig = baseUrlConfig;
    }

    /*买家模块*/

    /**
     * 获取商品详细信息
     *
     * @param productId 商品id
     * @return BaseProductDTO
     */
    @Override
    public GeneralResponse getProductByBuyer(Integer productId) {
        BaseProductDTO product;
        try {
            product = elasticSearchMapper.searchProduct(productId);
        } catch (IOException e) {
            return GeneralResponse.fail(ResponseStatusCode.ES_CLIENT_FAILED);
        }
        if (product == null) {
            return GeneralResponse.fail(ResponseStatusCode.NO_CORRESPONDING_RESULT);
        }
        return GeneralResponse.success(product);
    }

    /**
     * 查询商品
     *
     * @param page 分页参数(索引从0开始)
     * @return ProductDTO列表
     */
    @Override
    public GeneralResponse searchProduct(Integer page) {
        try {
            return GeneralResponse.success(elasticSearchMapper.search(page));
        } catch (Exception e) {
            if ("非法请求".equals(e.getMessage())) {
                return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
            }
            return GeneralResponse.fail(ResponseStatusCode.ES_CLIENT_FAILED);
        }
    }

    /**
     * 查询商品
     *
     * @param word 查询词
     * @param page 分页参数(索引从0开始)
     * @return ProductDTO列表
     */
    @Override
    public GeneralResponse searchProductByWord(String word, Integer page) {
        try {
            return GeneralResponse.success(elasticSearchMapper.searchByKeyword(word, page));
        } catch (Exception e) {
            if ("非法请求".equals(e.getMessage())) {
                return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
            }
            return GeneralResponse.fail(ResponseStatusCode.ES_CLIENT_FAILED);
        }
    }

    /**
     * 查询商品评论信息
     *
     * @param productId 商品id
     * @param page      分页参数(索引从0开始)
     * @return CommentDTO列表
     */
    @Override
    public GeneralResponse getRemarkList(Integer productId, Integer page) {
        List<CommentShowDO> comments = productMapper.getCommentList(productId, 10 * page).stream().map(CommentShowDO::new).collect(Collectors.toList());  //映射到CommentDTO
        CommentListDTO commentList = new CommentListDTO(productMapper.getCommentNumber(productId), comments);
        return GeneralResponse.success(commentList);
    }

    /**
     * 获取用户购物车列表
     *
     * @param userId 用户id
     * @param page   分页参数(索引从0开始)
     * @return CartDTO列表
     */
    @Override
    public GeneralResponse getCartList(Integer userId, Integer page) {
        return GeneralResponse.success(productMapper.getCartList(userId, page * 10));
    }

    /**
     * 添加商品到购物车
     *
     * @param userId    用户id
     * @param productId 商品id
     * @param num       商品数量
     * @return 是否添加成功
     */
    @Override
    public GeneralResponse addProductToCart(Integer userId, Integer productId, Integer num) {
        Integer originNumber = productMapper.getProductNumberFromCart(userId, productId);
        if (originNumber == null) {  //购物车中没有该商品
            productMapper.addNewProductToCart(userId, productId, num);
            return GeneralResponse.success();
        } else {
            System.out.println(num+originNumber);
            if (productMapper.updateProductOnCart(userId, productId, num + originNumber)) {
                return GeneralResponse.success();
            }
        }
        return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
    }

    /**
     * 修改购物车商品数量
     *
     * @param userId    用户id
     * @param productId 商品id
     * @param num       商品数量
     * @return 是否添加成功
     */
    @Override
    public GeneralResponse updateProductToCart(Integer userId, Integer productId, Integer num) {
        if (productMapper.getProductNumberFromCart(userId, productId) == null) {  //购物车中没有该商品
            return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
        }
        if (productMapper.updateProductOnCart(userId, productId, num)) {
            return GeneralResponse.success();
        }
        return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);  //更新失败
    }

    /**
     * 删除购物车商品
     *
     * @param userId    用户id
     * @param productId 商品id
     * @return 是否添加成功
     */
    @Override
    public GeneralResponse removeProductFromCart(Integer userId, Integer productId) {
        if (productMapper.removeProductFromCart(userId, productId)) {
            return GeneralResponse.success();
        }
        return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
    }

    /*卖家模块*/

    /**
     * 获取商品详细信息
     *
     * @param productId 商品id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getProductBySeller(Integer productId) {
        return GeneralResponse.success(productMapper.getProductByProductId(productId));
    }

    /**
     * 获取商品列表
     *
     * @param storeId 店铺id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getProductManageList(Integer storeId, Integer page) {
        ProductResponseDTO productResponseDTO = new ProductResponseDTO(
                productMapper.getProductsByStoreId(storeId, page*10),
                (long) productMapper.getProductNumberByStoreId(storeId));
        return GeneralResponse.success(productResponseDTO);
    }

    /**
     * 停售/重售商品
     *
     * @param storeId   店铺id
     * @param productId 商品id
     * @return 响应信息
     */
    @Override
    public GeneralResponse updateStatus(Integer storeId, Integer productId,ProductStatusCode statusCode) {
        if(!productMapper.updateProductInfo(storeId,productId,null,null,null, statusCode.getStatusCode())){
            return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
        }
        //从搜索引擎中删除
        if(statusCode.equals(ProductStatusCode.OUT_OF_SALE)){
            if(!elasticSearchMapper.deleteProduct(productId)){
                return GeneralResponse.fail(ResponseStatusCode.ES_CLIENT_FAILED);
            }
        }else {
            if(!elasticSearchMapper.pushProductFromDatabase(productId)){
                return GeneralResponse.fail(ResponseStatusCode.ES_CLIENT_FAILED);
            }
        }
        return GeneralResponse.success();
    }

    /**
     * 上传商品
     *
     * @param storeId 店铺id
     * @param title   商品标题
     * @param price   商品价格
     * @param picture 图片
     * @return 响应信息
     */
    @Override
    public GeneralResponse upload(Integer storeId, String title, Double price, MultipartFile picture) {
        String basePath=baseUrlConfig.getBasePath();
        String[] pictureSplitArray=picture.getOriginalFilename().split("\\.");
        String filePath=String.format("%s.%s", IdUtil.fastSimpleUUID(), pictureSplitArray[pictureSplitArray.length-1]);
        String urlPath=baseUrlConfig.getBaseUrl()+filePath;
        //保存文件
        try {
            File file = new File(new File(basePath).getCanonicalFile(), filePath);
            picture.transferTo(file);
        }catch (IOException e){
            return GeneralResponse.fail(ResponseStatusCode.FILE_SYSTEM_FAILED);
        }
        ProductPO product=new ProductPO(null,storeId,title,price,urlPath,ProductStatusCode.ON_SALE.getStatusCode());
        if(!productMapper.insertProductInfo(product)){
            return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
        }
        elasticSearchMapper.pushProductFromDatabase(product.getProductId());
        return GeneralResponse.success();
    }

    /**
     * 修改商品信息
     *
     * @param storeId   店铺id
     * @param productId 商品id
     * @param title     商品标题
     * @param price     商品价格
     * @param picture   图片
     * @return 响应信息
     */
    @Override
    public GeneralResponse update(Integer storeId, Integer productId, String title, Double price, MultipartFile picture) {
        String urlPath=null;
        if(picture!=null&&(!picture.isEmpty())){
            String basePath=baseUrlConfig.getBasePath();
            String[] pictureSplitArray=picture.getOriginalFilename().split("\\.");
            String filePath=String.format("%s.%s", IdUtil.fastSimpleUUID(), pictureSplitArray[pictureSplitArray.length-1]);
            urlPath=baseUrlConfig.getBaseUrl()+filePath;
            //保存文件
            try {
                File file = new File(new File(basePath).getCanonicalFile(), filePath);
                System.out.println(file);
                picture.transferTo(file);
            }catch (IOException e){
                return GeneralResponse.fail(ResponseStatusCode.FILE_SYSTEM_FAILED);
            }
        }
        if(!productMapper.updateProductInfo(storeId,productId,title,price,urlPath,null)){
            return GeneralResponse.fail(ResponseStatusCode.ILLEGAL_REQUEST);
        }
        elasticSearchMapper.pushProductFromDatabase(productId);
        return GeneralResponse.success();
    }
}
